import { createScene } from '@/scene.js';
import { createCity } from '@/city.js';
import * as buildingFactory from '@/buildings.js';

export function createGame() {
  let selectedControl = document.getElementsByClassName('ui-button')[0];

  /** @type {import('./type').ButtonId} */
  let activeToolId = document.getElementsByClassName('ui-button')[0].id.split('-')[1];

  let isPaused = false;

  const scene = createScene();
  const city = createCity(16);

  scene.initialize(city);

  addEventListener('wheel', scene.cameraManager.handleMouseScroll);
  addEventListener('mousedown', handleMouseDown);
  addEventListener('mousemove', handleMouseMove);
  addEventListener('resize', scene.handleResize);
  addEventListener('contextmenu', event => event.preventDefault())

  function update() {
    if (isPaused) { return; }
    // 先更新城市数据模型，再更新场景
    city.update();
    scene.update(city);
  }

  function togglePause() {
    isPaused = !isPaused;
    document.getElementById('button-pause').innerHTML = isPaused ? 'RESUME' : 'PAUSE';
  }

  /**
   * @param {MouseEvent} event 
   */
  function handleMouseDown(event) {
    if (0 == event.button) {
      const selectedObject = scene.getSelectedObject(event);
      useActiveTool(selectedObject);
    }
  }

  /** 上次鼠标移动的时候 */
  let lastMove = new Date();

  /**
   * @param {MouseEvent} event 
   */
  function handleMouseMove(event) {
    // 避免执行次数太多导致浏览器崩溃
    if (Date.now() - lastMove < (1/60)) { return; }
    lastMove = Date.now();

    const hoverObject = scene.getSelectedObject(event);
    scene.setHighlightedObject(hoverObject);

    // 若鼠标左键按下，则使用此工具
    if (hoverObject && event.buttons & 1) {
      useActiveTool(hoverObject);
    }

    scene.cameraManager.handleMouseMove(event);
  }

  /**
   * @param {MouseEvent} event 
   */
  function handleToolSelected(event) {
    if (selectedControl) {
      selectedControl.classList.remove('selected');
    }
    selectedControl = event.target;
    selectedControl.classList.add('selected');

    activeToolId = selectedControl.id.split('-')[1];
    console.log(activeToolId);
  }

  function useActiveTool(object) {
    if (!object) {
      updateInfoPanel(null);
      return;
    }

    const { x, y } = object.userData;
    const tile = city.tiles[x][y];

    if ('select' == activeToolId) {
      scene.setActiveObject(object);
      updateInfoPanel(tile);
    } else if ('bulldoze' == activeToolId) {
      bulldoze(tile);
    } else if (!tile.building) {
      placeBuilding(tile);
    }
  }

  function updateInfoPanel(tile) {
    document.getElementById('selected-object-info').innerHTML = tile ? JSON.stringify(tile, ' ', 2) : '';
  }

  function bulldoze(tile) {
    console.log(activeToolId);
    tile.building = void 0;
    scene.update(city);
    console.log(tile);
  }

  function placeBuilding(tile) {
    console.log(activeToolId);
    tile.building = buildingFactory[activeToolId]();
    scene.update(city);
    console.log(tile);
  }

  setInterval(() => {
    update();
  }, 1000);

  scene.start();

  return {
    update,
    handleToolSelected,
    togglePause,
  };
}
